﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Data.SQLite;
using System.Web;
using BfLib.Text;

namespace BfLib.Data
{
    public class FirefoxCookieStore : SQLiteBaseDAL
    {
        string _CookieFile = string.Empty;
        string _ConnectionString = string.Empty;
        SQLiteCommand _cmd;

        public FirefoxCookieStore(string CookieFile, bool ReadOnly = false)
        {
            _CookieFile = CookieFile;
            if (!File.Exists(_CookieFile))
            {
                throw new Exception("Sqlite DB not found");
            }

            if (!ReadOnly)
            {
                _ConnectionString = String.Format("Data Source={0};Version=3;", _CookieFile);
            }
            else
            {
                _ConnectionString = String.Format("Data Source={0};Version=3;Read Only=True;", _CookieFile); 
            }
        }

        public static string CookieCollectionToHeaderValue(HttpCookieCollection cookies)
        {
            StringBuilder sb = new StringBuilder(255);
            HttpCookie cookie;

            foreach (string s in cookies)
            {
                cookie = cookies[s];
                sb.Append(String.Format(" {0}={1};", cookie.Name, cookie.Value));
            }

            string hval = sb.ToString().Trim();
            if (hval.Length > 0)
            {
                hval = hval.Substring(0, hval.Length - 1);
            }

            return hval;
        }

        public HttpCookieCollection GetCookiesForURL(string url)
        {
            Uri uri = new Uri(url);
            if(!uri.IsAbsoluteUri)
            {
                return null;
            }
            if ("https|http".IndexOf(uri.Scheme.ToLower()) < 0)
            {
                return null;
            }

            bool secure = string.Compare(uri.Scheme, "https", true) == 0;
            string sql = string.Empty;
            string path = uri.PathAndQuery;
            string dhost = string.Empty;

            if (path.IndexOf("?") >= 0)
            {
                path = path.Substring(0, path.IndexOf("?"));
            }

            int sfi = path.IndexOf("/");
            int sli = path.LastIndexOf("/");

            if (sfi != sli)
            {
                path = path.Substring(0, sli);
            }
            else
            {
                path = "/";
            }

            /* AND isSecure=1;", */


            if (uri.Host.ToLower().StartsWith("www."))
            {
                dhost = uri.Host.Substring(4);
            }
            else
            {
                dhost = uri.Host;
            }


            if(secure)
            {
                sql = String.Format(
                    "SELECT * FROM moz_cookies WHERE (host='{0}' OR host='.{1}' OR host='{2}' OR host='.{3}') AND (path='{4}' OR path='/');",
                    uri.Host, uri.Host, dhost, dhost, path);
            }  
            else
            {
                sql = String.Format(
                    "SELECT * FROM moz_cookies WHERE (host='{0}' OR host='.{1}' OR host='{2}' OR host='.{3}') AND (path='{4}' OR path='/') AND isSecure=0;",
                    uri.Host, uri.Host, dhost, dhost, path);
                      
				///something not right with the sql statements
                //   SELECT * FROM moz_cookies WHERE (host=''%s'' OR host=''.%s'' OR host=''%s'' OR host=''.%s'') AND (path=''%s'' OR path=''/'') AND isSecure=0;
                //'SELECT * FROM moz_cookies WHERE (host=''%s'' OR host=''.%s'' OR host=''%s'' OR host=''.%s'') AND (path=''%s'' OR path=''/'') AND isSecure=0;';
            }


            this._cmd = new SQLiteCommand();
            this._cmd.CommandText = sql;
            DataTable dt = GetDataTable(this._ConnectionString, this._cmd);
            HttpCookie cookie;
            HttpCookieCollection cookies = new HttpCookieCollection();
            foreach (DataRow dr in dt.Rows)
            {
                cookie = new HttpCookie(StringLib.EnsureString(dr["name"]));
                cookie.Domain = StringLib.EnsureString(dr["name"]);
                cookie.Path = StringLib.EnsureString(dr["path"]);
                cookie.Value = StringLib.EnsureString(dr["value"]);
                cookie.Expires = StringLib.UnixStrToDateTime( StringLib.EnsureString(dr["expiry"]), true  );
                cookies.Add(cookie);
            }

            return cookies;
        }
    }
}
